﻿/* 
 * 1.    Create new console application "Evolution"
 * 2.       Fill 30x30 matrix randomly by 1-value and zero values.
 * 3.       0- the cell is empty
 * 4.       1- te cell includes smth
 * 5.       Print it  as set of spaces and asterisks
 * 6.       Do the following operations under the matrix cells on Enter pressing 
 * 7.       1)  in case the cell is empty (zero value) and at least two neigbours are 1-value cells, fill the cell with 1-value.
 * 8.       2)  in case all the cells are 1-value cells and all around cells are set to 1-value, set the value to zero.
 * 
 */

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Evolution
{
    class Evolutionmatrix
    {
        private int size = 0;
        private int[,] arr;


        //create matrix and fill it randomly by 1 and 0
        public Evolutionmatrix(int lsize)
        {
            int i, j;
            this.size = lsize;

            Random rnd = new Random(DateTime.Now.Millisecond);


            arr = new int[size, size];
            for (i = 0; i < size; i++)
            {
                for (j = 0; j < size; j++)
                {
                    arr[i, j] = (rnd.Next(1, 101) % 2 == 0) ? 0 : 1;

                }
            }

        }

        //display matrix with " " instead of 0 and "*" instead of 1 
        public void Print()
        {

            for (int i = 0; i < this.size; i++)
            {
                for (int j = 0; j < this.size; j++)
                {
                    Console.Write((arr[i, j] == 0 ? ' ' : '*'));
                }
                Console.WriteLine(' ');
            }

        }


        //check if the n and m are valid indexes and in case they are, return corresponding value from the matrix. Othervice, return 0.
        //this function is utility one, and used to get information about surrounding cells.
        private int isExist(int n, int m)
        {
            return ((n >= 0 && m >= 0 && n < size && m < size) ? arr[n, m] : 0);
        }

        //it is simple. The function returns the number of the cell's neigbours.
        private int numOfNeighbors(int n, int m)
        {

            //we are on the firs or the last line of matrix
            if ((n - 1) < 0 || n + 1 == size)
            {
                if (m == 0 || m == size - 1)
                {
                    return 3;
                }
                else
                {
                    return 5;
                }
            }

            //we are on the first or the last column of matrix
            if (m - 1 < 0 || m + 1 == size)
            {
                return 5;
            }

            return 8;
        }



        //function to recalculate the next evolution step.
        public void Recalculate()
        {
            int i, j;
            int tmp;

            int[,] tmp_arr = new int[size, size];

            for (i = 0; i < size; i++)
            {
                for (j = 0; j < size; j++)
                {
                    tmp = isExist(i - 1, j - 1) + isExist(i - 1, j) + isExist(i - 1, j + 1) +
                          isExist(i,     j - 1) +                     isExist(i,     j + 1) +
                          isExist(i + 1, j - 1) + isExist(i + 1, j) + isExist(i + 1, j + 1);

                    //if the cell is zero and it has at least 2 1-value neigbours set it to 1 value, otherwise it has to be set to zero.
                    if (arr[i, j] == 0)
                    {
                        if (tmp >= 2)
                        {
                            tmp_arr[i, j] = 1;
                        }
                        else
                        {
                            tmp_arr[i, j] = 0;
                        }

                    }
                    else
                    {
                        //if the cell is 1value and it has only 1-value cells around it set it to zero
                        if (tmp == numOfNeighbors(i, j))
                        {
                            tmp_arr[i, j] = 0;
                        }
                        else
                        {
                            tmp_arr[i, j] = 1;
                        }
                    }

                }

            }


            arr = (int[,])(tmp_arr.Clone());

        }


    }
    




    class Program
    {
        static void Main(string[] args)
        {

           
            Evolutionmatrix mtrx = new Evolutionmatrix(30);
            mtrx.Print();
             

            while((Console.ReadKey()).Key == ConsoleKey.Enter)
            {  
               mtrx.Recalculate();
               mtrx.Print();
 
            }


        }
    }
}
